package com.ypj.rpc.handler;

import com.ypj.rpc.entity.RpcRequest;
import com.ypj.rpc.entity.RpcResponse;
import com.ypj.rpc.enumeration.ResponseCode;
import com.ypj.rpc.provider.ServiceProvider;
import com.ypj.rpc.provider.ServiceProviderImpl;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 利用反射调用方法
 */
@Slf4j
public class RequestHandler {

    //本地服务提供者，保存了服务端提供的所有服务
    private static final ServiceProvider serviceProvider;

    static {
        serviceProvider=new ServiceProviderImpl();
    }

    public Object handle(RpcRequest request){
        Object result=null;
        Object service=serviceProvider.getServiceProvider(request.getInterfaceName());
        try {
            result=invokeTargetMethod(request,service);
            log.info("服务：{}成功调用方法：{}",request.getInterfaceName(),request.getMethodName());
        } catch (IllegalAccessException | InvocationTargetException e) {
            log.error("调用或发送时有错误发生："+e.getMessage(),e);
        }
        return result;

    }
    private Object invokeTargetMethod(RpcRequest request,Object service) throws InvocationTargetException, IllegalAccessException {
        Method method;
        try {
            method=service.getClass().getMethod(request.getMethodName(),request.getParamTypes());
        } catch (NoSuchMethodException e) {
            return RpcResponse.fail(ResponseCode.NOT_FOUND_METHOD,request.getRequestId());
        }
        return method.invoke(service,request.getParameters());
    }
}
